vim9script noclear

if exists("g:autoparis")
	finish
endif

g:autopairs = 1

var chars = {'(': ')', '[': ']', '{': '}', '"': '"', "'": "'", "`": "`"}

def SmartKey(key1: string, key2: string): string
	var line = getline('.')
	var col = col('.')

	if chars->has_key(line[col - 2]) && chars[line[col - 2]] == line[col - 1]
		return key1
	else
		return key2
	endif
enddef

def SmartPrev(ch: string): string
	var next = getline(".")[col('.') - 1]

	if next == v:null || next !~ '\w'
		return $"{ch}{chars[ch]}\<Left>"
	endif

	return ch
enddef

def SmartPost(ch: string): string
	var next = getline(".")[col('.') - 1]

	if ch == next
		return "\<Right>"
	endif

	return ch
enddef

def SmartBoth(ch: string): string
	var line = getline('.')
	var col = col('.')
	var prev = line[col - 2]
	var next = line[col - 1]

	if next == ch
		return "\<Right>"
	elseif (prev == v:null) || prev =~ '\W' && (next =~ '\W' || next == v:null)
		return $"{ch}{ch}\<Left>"
	else
		return ch
	endif
enddef

inoremap <expr> ( <SID>SmartPrev('(')
inoremap <expr> [ <SID>SmartPrev('[')
inoremap <expr> { <SID>SmartPrev('{')

inoremap <expr> ) <SID>SmartPost(")")
inoremap <expr> ] <SID>SmartPost("]")
inoremap <expr> } <SID>SmartPost("}")

inoremap <expr> " <SID>SmartBoth('"')
inoremap <expr> ' <SID>SmartBoth("'")
inoremap <expr> ` <SID>SmartBoth("`")

inoremap <expr> <CR> <SID>SmartKey("\<CR>\<C-o>O", "\<CR>")
inoremap <expr> <BS> <SID>SmartKey("\<Right>\<BS>\<BS>", "\<BS>")
